package algorithm.sphericharmonics;

import algorithm.fft.Complex;

public class Util {
	public static final float PI=3.14159265358979f; 
	public static final float MY_EPSILON=1e-6f;
	public static final Complex ZERO_COMPLEX=new Complex(0,0);
	public static void memset(float[] array, int fromIndex, int toIndex, float val){
		java.util.Arrays.fill(array, fromIndex, toIndex, val); 
	}
	public static void memset(Complex[] array,int fromIndex,int toIndex,Complex val){
		for (int i=fromIndex; i<toIndex; i++){
			array[i].setIm(val.getIm()); 
			array[i].setRe(val.getRe()); 
		}
	}
	public static float findSmallestEl( float[] theVect, int nEl){
		  int i;
		  float minEl;
		  float absMinEl;

		  minEl = theVect[0];
		  absMinEl = Math.abs(theVect[0]);
		  for( i = 1; i < nEl; i++ ) {
		    if(Math.abs(theVect[i]) < absMinEl){
		      absMinEl = Math.abs(theVect[i]);
		      minEl = theVect[i];
		    }
		  }
		  return(minEl);
	}
	public static int ccSHT_round(float a){
		if( a >= 0 ) {
		    return((int)(a+0.5));
		}
		 return((int)(a-0.5));
	}
	/*
	 * In order to store a set of spherical harmonic coefficients in memory we must define 
	 * a way of vectorizing the set. To insure efficient memory access we have chosen to 
	 * index in l major order since the calculation is done with this ordering. In the 
	 * header file ccSHT.h there is a macro called almIndex which takes three integers 
	 * (l,m,lmax) and returns a linear indexing. This ordering is l major, and increasing
	 *  with both l and m and is defined below (note that lmax has been replaced by L for 
	 *  clarity):
 	 *  almIndex(l,m,L) = (L*(L+1+2*m)+m*(2-abs(m+1)))/2+l
 	 * This implies that an a_{l,m} vector would be written:

	 *[ a_{L,-L}, a_{L-1,-L+1}, a_{L,-L+1}, a_{L-2,-L+2}, ... , a_{0,0}, a_{1,0}, ... , a_{L,L} ]

	 * This is the ordering for the output of forwardSHT and the input for backwardSHT. 
     */
	public static int almIndex(int l,int m,int L) {
		return ( (((L)*((L) + 2*(m) + 1)) + (m)*(2 - ( ((m) >= -1) ? ((m) + 1) : (-((m) + 1)) ) ))/2 + (l));
	}
	/*
	 * There is a function for computing scaled associated Legendre polynomials called 
	 * calculateQlm(). The data vector created by this function also uses an indexing scheme which is l major and increasing with both l and m. It is also defined in the header file ccSHT.h with the macro called Qindex which is defined:
	 * Qindex(l,m,L) = L*m - (m*(m-1))/2 + l
     * Therefore a Q_{l,m} vector would be written:

     * [ Q_{0,0}, Q_{1,0}, ... , Q_{L,0}, Q_{1,1}, Q_{2,1}, ... , Q_{L, L} ]

	 * This is the ordering for the output of calculateQlm(). 
	 */
	public static int Qindex(int l, int m,int L){
		return L*m - (m*(m-1))/2 + l;  
	}	
	public static int pown1(int a) { 
		return  (((a)%2!=0) ? (-1) : (1)); 
	}
	public static int abs(int x){
		return x>0?x:-x;
	}
	public static int myMod( int a, int b){
	  int c;
	  b = abs(b);
	  c = a%b;
	  if( c < 0 ){
	    c += b;
	  }
	  return(c);
	}
}
